package com.ysstech.activiti.service.impl;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.ysstech.activiti.service.ActivitiRuntimeService;
import com.ysstech.common.exception.BusinessException;
import lombok.extern.slf4j.Slf4j;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.bpmn.model.FlowElement;
import org.activiti.bpmn.model.GraphicInfo;
import org.activiti.engine.IdentityService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.task.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Slf4j
@Service
public class ActivitiRuntimeServiceImpl implements ActivitiRuntimeService {
    @Autowired
    private RuntimeService runtimeService;
    @Autowired
    private IdentityService identityService;
    @Autowired
    private TaskService taskService;
    @Autowired
    private RepositoryService repositoryService;

    /**
     * 通过流程key启动一个流程
     *
     * @param key
     * @param id
     * @throws Exception
     */
    @Override
    public void startProcessFlow(String userId, String key, String id) throws Exception {
        Map<String, Object> variables = new HashMap<>();
        identityService.setAuthenticatedUserId(userId);//流程发起人
        //格式：LeaveBill.id的形式（使用流程变量）
        String objId = key + "." + id;
        variables.put("objId", objId);
        //通过objId查询是不是存在
        List<Task> task = taskService.createTaskQuery().processInstanceBusinessKey(objId).list();
        if (task != null && task.size() > 0) {
            throw new BusinessException("此交易还未授权通过，正在等待授权！");
        }
        // 使用流程定义的key，启动流程实例，同时设置流程变量，同时向正在执行的执行对象表中的字段BUSINESS_KEY添加业务数据，同时让流程关联业务
        runtimeService.startProcessInstanceByKey(key, objId, variables);
    }

    /**
     * 二：查看当前活动，获取当期活动对应的坐标x,y,width,height，将4个值存放到Map<String,Object>中
     * map集合的key：表示坐标x,y,width,height
     * map集合的value：表示坐标对应的值
     */
    public Map<String, Object> queryProcessFlowByTask(String taskId) throws Exception {
        //存放坐标
        Map<String, Object> map = new HashMap<>();
        //使用任务ID，查询任务对象
        Task task = taskService.createTaskQuery()//
                .taskId(taskId)//使用任务ID查询
                .singleResult();
        //获取流程定义的ID
        if (null == task) {
            throw new BusinessException("此流程已经结束！");
        }
        String processDefinitionId = task.getProcessDefinitionId();
        //获取流程定义的实体对象（对应.bpmn文件中的数据）
        ProcessDefinition processDefinition = repositoryService.getProcessDefinition(processDefinitionId);
        BpmnModel bpmnModel = repositoryService.getBpmnModel(task.getProcessDefinitionId());
        //获取当前活动对象
        FlowElement flowElement = bpmnModel.getFlowElement(task.getTaskDefinitionKey());
        GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowElement.getId());
        map.put("x", graphicInfo.getX());
        map.put("y", graphicInfo.getY());
        map.put("width", graphicInfo.getWidth());
        map.put("height", graphicInfo.getHeight());
        map.put("deploymentId", processDefinition.getDeploymentId());//流程编号
        map.put("imageName", processDefinition.getDiagramResourceName());//图片名称
        return map;
    }

}
